home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / pctv2n2.arc / L2.ASM < prev    next >
Assembly Source File  |  1991-08-11  |  13KB  |  323 lines

  1. ; Low-level animation routines.
  2. ; Tested with TASM 2.0.
  3.  
  4. SCREEN_WIDTH    equ     80      ;screen width in bytes
  5. INPUT_STATUS_1  equ     03dah   ;Input Status 1 register
  6. CRTC_INDEX      equ     03d4h   ;CRT Controller Index reg
  7. START_ADDRESS_HIGH equ  0ch     ;bitmap start address high byte
  8. START_ADDRESS_LOW equ   0dh     ;bitmap start address low byte
  9. GC_INDEX        equ     03ceh   ;Graphics Controller Index reg
  10. SET_RESET       equ     0       ;GC index of Set/Reset reg
  11. G_MODE          equ     5       ;GC index of Mode register
  12.  
  13.         .model  small
  14.         .data
  15. BIOS8x8Ptr dd   ?       ;points to BIOS 8x8 font
  16. ; Tables used to look up left and right clip masks.
  17. LeftMask db     0ffh, 07fh, 03fh, 01fh, 00fh, 007h, 003h, 001h
  18. RightMask db    080h, 0c0h, 0e0h, 0f0h, 0f8h, 0fch, 0feh, 0ffh
  19.  
  20.         .code
  21. ; Draws the specified filled rectangle in the specified color.
  22. ; Assumes the display is in mode 12h. Does not clip and assumes
  23. ; rectangle coordinates are valid.
  24. ;
  25. ; C near-callable as: void DrawRect(int LeftX, int TopY, int RightX,
  26. ;       int BottomY, int Color, unsigned int ScrnOffset,
  27. ;       unsigned int ScrnSegment);
  28.  
  29. DrawRectParms   struc
  30.         dw      2 dup (?) ;pushed BP and return address
  31. LeftX   dw      ?       ;X coordinate of left side of rectangle
  32. TopY    dw      ?       ;Y coordinate of top side of rectangle
  33. RightX  dw      ?       ;X coordinate of right side of rectangle
  34. BottomY dw      ?       ;Y coordinate of bottom side of rectangle
  35. Color   dw      ?       ;color in which to draw rectangle (only the
  36.                         ; lower 4 bits matter)
  37. ScrnOffset dw   ?       ;offset of base of bitmap in which to draw
  38. ScrnSegment dw  ?       ;segment of base of bitmap in which to draw
  39. DrawRectParms   ends
  40.  
  41.         public  _DrawRect
  42. _DrawRect       proc    near
  43.         push    bp      ;preserve caller's stack frame
  44.         mov     bp,sp   ;point to local stack frame
  45.         push    si      ;preserve caller's register variables
  46.         push    di
  47.  
  48.         cld
  49.         mov     dx,GC_INDEX
  50.         mov     al,SET_RESET
  51.         mov     ah,byte ptr Color[bp]
  52.         out     dx,ax   ;set the color in which to draw
  53.         mov     ax,G_MODE + (0300h)
  54.         out     dx,ax   ;set to write mode 3
  55.         les     di,dword ptr ScrnOffset[bp] ;point to bitmap start
  56.         mov     ax,SCREEN_WIDTH
  57.         mul     TopY[bp]        ;point to the start of the top scan
  58.         add     di,ax           ; line to fill
  59.         mov     ax,LeftX[bp]
  60.         mov     bx,ax
  61.         shr     ax,1    ;/8 = byte offset from left of screen
  62.         shr     ax,1
  63.         shr     ax,1
  64.         add     di,ax   ;point to the upper left corner of fill area
  65.         and     bx,7    ;isolate intrapixel address
  66.         mov     dl,LeftMask[bx] ;set the left-edge clip mask
  67.         mov     bx,RightX[bp]
  68.         mov     si,bx
  69.         and     bx,7    ;isolate intrapixel address of right edge
  70.         mov     dh,RightMask[bx] ;set the right-edge clip mask
  71.         mov     bx,LeftX[bp]
  72.         and     bx,NOT 7 ;intrapixel address of left edge
  73.         sub     si,bx
  74.         shr     si,1
  75.         shr     si,1
  76.         shr     si,1    ;# of bytes across spanned by rectangle - 1
  77.         jnz     MasksSet ;if there's only one byte across,
  78.         and     dl,dh   ; combine the masks
  79. MasksSet:
  80.         mov     bx,BottomY[bp]
  81.         sub     bx,TopY[bp] ;# of scan lines to fill - 1
  82. FillLoop:
  83.         push    di      ;remember line start offset
  84.         mov     al,dl   ;left edge clip mask
  85.         xchg    es:[di],al ;draw the left edge
  86.         inc     di      ;point to the next byte
  87.         mov     cx,si   ;# of bytes left to do
  88.         dec     cx      ;# of bytes left to do - 1
  89.         js      LineDone ;that's it if there's only 1 byte across
  90.         jz      DrawRightEdge ;no middle bytes if only 2 bytes across
  91.         mov     al,0ffh ;non-edge bytes are solid
  92.         rep     stosb   ;draw the solid bytes across the middle
  93. DrawRightEdge:
  94.         mov     al,dh   ;right edge clip mask
  95.         xchg    es:[di],al ;draw the right edge
  96. LineDone:
  97.         pop     di      ;retrieve line start offset
  98.         add     di,SCREEN_WIDTH ;point to the next line
  99.         dec     bx      ;count off scan lines
  100.         jns     FillLoop
  101.  
  102.         pop     di      ;restore caller's register variables
  103.         pop     si
  104.         pop     bp      ;restore caller's stack frame
  105.         ret
  106. _DrawRect       endp
  107.  
  108. ; Shows the page at the specified offset in the bitmap. Page is
  109. ; displayed when this routine returns.
  110. ;
  111. ; C near-callable as: void ShowPage(unsigned int StartOffset);
  112.  
  113. ShowPageParms   struc
  114.         dw      2 dup (?) ;pushed BP and return address
  115. StartOffset dw  ?       ;offset in bitmap of page to display
  116. ShowPageParms   ends
  117.  
  118.         public  _ShowPage
  119. _ShowPage       proc    near
  120.         push    bp      ;preserve caller's stack frame
  121.         mov     bp,sp   ;point to local stack frame
  122. ; Wait for display enable to be active (status is active low), to be
  123. ; sure both halves of the start address will take in the same frame.
  124.         mov     bl,START_ADDRESS_LOW        ;preload for fastest
  125.         mov     bh,byte ptr StartOffset[bp] ; flipping once display
  126.         mov     cl,START_ADDRESS_HIGH        ; enable is detected
  127.         mov     ch,byte ptr StartOffset+1[bp]
  128.         mov     dx,INPUT_STATUS_1
  129. WaitDE:
  130.         in      al,dx
  131.         test    al,01h
  132.         jnz     WaitDE  ;display enable is active low (0 = active)
  133. ; Set the start offset in display memory of the page to display.
  134.         mov     dx,CRTC_INDEX
  135.     mov    ax,bx
  136.         out     dx,ax    ;start address low
  137.     mov    ax,cx
  138.         out     dx,ax    ;start address high
  139. ; Now wait for vertical sync, so the other page will be invisible when
  140. ; we start drawing to it.
  141.         mov     dx,INPUT_STATUS_1
  142. WaitVS:
  143.         in      al,dx
  144.         test    al,08h
  145.         jz      WaitVS  ;vertical sync is active high (1 = active)
  146.         pop     bp      ;restore caller's stack frame
  147.         ret
  148. _ShowPage       endp
  149.  
  150. ; Displays the specified image at the specified location in the
  151. ; specified bitmap, in the desired color.
  152. ;
  153. ; C near-callable as: void DrawImage(int LeftX, int TopY,
  154. ;       image **RotationTable, int Color, unsigned int ScrnOffset,
  155. ;       unsigned int ScrnSegment);
  156.  
  157. DrawImageParms  struc
  158.         dw      2 dup (?) ;pushed BP and return address
  159. DILeftX dw      ?       ;X coordinate of left side of image
  160. DITopY  dw      ?       ;Y coordinate of top side of image
  161. RotationTable dw ?      ;pointer to table of pointers to image
  162.                         ; rotations
  163. DIColor dw      ?       ;color in which to draw image (only the
  164.                         ; lower 4 bits matter)
  165. DIScrnOffset dw ?       ;offset of base of bitmap in which to draw
  166. DIScrnSegment dw ?      ;segment of base of bitmap in which to draw
  167. DrawImageParms  ends
  168.  
  169. image struc
  170. WidthInBytes    dw      ?
  171. Height          dw      ?
  172. BitPattern      dw      ?
  173. image ends
  174.  
  175.         public  _DrawImage
  176. _DrawImage      proc    near
  177.         push    bp      ;preserve caller's stack frame
  178.         mov     bp,sp   ;point to local stack frame
  179.         push    si      ;preserve caller's register variables
  180.         push    di
  181.  
  182.         cld
  183.         mov     dx,GC_INDEX
  184.         mov     al,SET_RESET
  185.         mov     ah,byte ptr DIColor[bp]
  186.         out     dx,ax   ;set the color in which to draw
  187.         mov     ax,G_MODE + (0300h)
  188.         out     dx,ax   ;set to write mode 3
  189.         les     di,dword ptr DIScrnOffset[bp] ;point to bitmap start
  190.         mov     ax,SCREEN_WIDTH
  191.         mul     DITopY[bp]      ;point to the start of the top scan
  192.         add     di,ax           ; line on which to draw
  193.         mov     ax,DILeftX[bp]
  194.         mov     bx,ax
  195.         shr     ax,1    ;/8 = byte offset from left of screen
  196.         shr     ax,1
  197.         shr     ax,1
  198.         add     di,ax   ;point to the upper left corner of draw area
  199.         and     bx,7    ;isolate intrapixel address
  200.         shl     bx,1    ;*2 for word look-up
  201.         add     bx,RotationTable[bp] ;point to the image structure for
  202.         mov     bx,[bx]              ; the intrabyte rotation
  203.         mov     dx,[bx].WidthInBytes ;image width
  204.         mov     si,[bx].BitPattern   ;pointer to image pattern bytes
  205.         mov     bx,[bx].Height       ;image height
  206. DrawImageLoop:
  207.         push    di      ;remember line start offset
  208.         mov     cx,dx   ;# of bytes across
  209. DrawImageLineLoop:
  210.         lodsb           ;get the next image byte
  211.         xchg    es:[di],al ;draw the next image byte
  212.         inc     di      ;point to the following screen byte
  213.         loop    DrawImageLineLoop
  214.         pop     di      ;retrieve line start offset
  215.         add     di,SCREEN_WIDTH ;point to the next line
  216.         dec     bx      ;count off scan lines
  217.         jnz     DrawImageLoop
  218.  
  219.         pop     di      ;restore caller's register variables
  220.         pop     si
  221.         pop     bp      ;restore caller's stack frame
  222.         ret
  223. _DrawImage      endp
  224.  
  225. ; Draws a 0-terminated text string at the specified location in the
  226. ; specified bitmap in white, using the 8x8 BIOS font. Must be at an X
  227. ; coordinate that's a multiple of 8.
  228. ;
  229. ; C near-callable as: void TextUp(char *Text, int LeftX, int TopY,
  230. ;       unsigned int ScrnOffset, unsigned int ScrnSegment);
  231.  
  232. TextUpParms     struc
  233.         dw      2 dup (?) ;pushed BP and return address
  234. Text    dw      ?       ;pointer to text to draw
  235. TULeftX dw      ?       ;X coordinate of left side of rectangle
  236.                         ; (must be a multiple of 8)
  237. TUTopY  dw      ?       ;Y coordinate of top side of rectangle
  238. TUScrnOffset dw ?       ;offset of base of bitmap in which to draw
  239. TUScrnSegment dw ?      ;segment of base of bitmap in which to draw
  240. TextUpParms     ends
  241.  
  242.         public  _TextUp
  243. _TextUp proc    near
  244.         push    bp      ;preserve caller's stack frame
  245.         mov     bp,sp   ;point to local stack frame
  246.         push    si      ;preserve caller's register variables
  247.         push    di
  248.  
  249.         cld
  250.         mov     dx,GC_INDEX
  251.         mov     ax,G_MODE + (0000h)
  252.         out     dx,ax   ;set to write mode 0
  253.         les     di,dword ptr TUScrnOffset[bp] ;point to bitmap start
  254.         mov     ax,SCREEN_WIDTH
  255.         mul     TUTopY[bp]      ;point to the start of the top scan
  256.         add     di,ax           ; line the text starts on
  257.         mov     ax,TULeftX[bp]
  258.         mov     bx,ax
  259.         shr     ax,1    ;/8 = byte offset from left of screen
  260.         shr     ax,1
  261.         shr     ax,1
  262.         add     di,ax   ;point to the upper left corner of first char
  263.         mov     si,Text[bp] ;point to text to draw
  264. TextUpLoop:
  265.         lodsb           ;get the next character to draw
  266.         and     al,al
  267.         jz      TextUpDone ;done if null byte
  268.         push    si      ;preserve text string pointer
  269.         push    di      ;preserve character's screen offset
  270.         push    ds      ;preserve default data segment
  271.         call    CharUp  ;draw this character
  272.         pop     ds      ;restore default data segment
  273.         pop     di      ;retrieve character's screen offset
  274.         pop     si      ;retrieve text string pointer
  275.         inc     di      ;point to next character's start location
  276.         jmp     TextUpLoop
  277.  
  278. TextUpDone:
  279.         pop     di      ;restore caller's register variables
  280.         pop     si
  281.         pop     bp      ;restore caller's stack frame
  282.         ret
  283.  
  284. CharUp:                 ;draws the character in AL at ES:DI
  285.         lds     si,[BIOS8x8Ptr] ;point to the 8x8 font start
  286.         mov     bl,al
  287.         sub     bh,bh
  288.         shl     bx,1
  289.         shl     bx,1
  290.         shl     bx,1    ;*8 to look up character offset in font
  291.         add     si,bx   ;point DS:SI to character data in font
  292.         mov     cx,8    ;characters are 8 high
  293. CharUpLoop:
  294.         movsb           ;copy the next character pattern byte
  295.         add     di,SCREEN_WIDTH-1 ;point to the next dest byte
  296.         loop    CharUpLoop
  297.         ret
  298. _TextUp endp
  299.  
  300. ; Sets the pointer to the BIOS 8x8 font.
  301. ;
  302. ; C near-callable as: extern void SetBIOS8x8Font(void);
  303.  
  304.         public  _SetBIOS8x8Font
  305. _SetBIOS8x8Font proc    near
  306.         push    bp      ;preserve caller's stack frame
  307.         push    si      ;preserve caller's register variables
  308.         push    di      ; and data segment (don't assume BIOS
  309.         push    ds      ; preserves anything)
  310.         mov     ah,11h  ;BIOS character generator function
  311.         mov     al,30h  ;BIOS information subfunction
  312.         mov     bh,3    ;request 8x8 font pointer
  313.         int     10h     ;invoke BIOS video services
  314.         mov     word ptr [BIOS8x8Ptr],bp ;store the pointer
  315.         mov     word ptr [BIOS8x8Ptr+2],es
  316.         pop     ds
  317.         pop     di      ;restore caller's register variables
  318.         pop     si
  319.         pop     bp      ;restore caller's stack frame
  320.         ret
  321. _SetBIOS8x8Font endp
  322.         end
  323.